var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { prebuild } from '@mintlify/prebuild';
import Chalk from 'chalk';
import express from 'express';
import fse, { pathExists } from 'fs-extra';
import got from 'got';
import { createServer } from 'http';
import isOnline from 'is-online';
import { pipeline } from 'node:stream/promises';
import { pathToFileURL } from 'node:url';
import open from 'open';
import { Server as SocketServer } from 'socket.io';
import tar from 'tar';
import { CLIENT_PATH, DOT_MINTLIFY, CMD_EXEC_PATH, TARGET_MINT_VERSION, VERSION_PATH, MINT_PATH, NEXT_SERVER_PATH, NEXT_STATIC_PATH, NEXT_CONFIG_PATH, TAR_URL, TAR_PATH, NEXT_PUBLIC_PATH, NEXT_PROPS_PATH, } from '../constants.js';
import { buildLogger, maybeFixMissingWindowsEnvVar } from '../util.js';
import listener from './listener/index.js';
const downloadTargetMint = (logger) => __awaiter(void 0, void 0, void 0, function* () {
    fse.emptyDirSync(MINT_PATH);
    logger.text = 'Downloading Mintlify framework...';
    yield pipeline(got.stream(TAR_URL), fse.createWriteStream(TAR_PATH));
    logger.text = 'Extracting Mintlify framework...';
    tar.x({
        sync: true,
        file: TAR_PATH,
        cwd: DOT_MINTLIFY,
    });
    fse.removeSync(TAR_PATH);
    fse.writeFileSync(VERSION_PATH, TARGET_MINT_VERSION);
});
const dev = (argv) => __awaiter(void 0, void 0, void 0, function* () {
    const logger = buildLogger('Preparing local Mintlify instance...');
    yield fse.ensureDir(DOT_MINTLIFY);
    const versionString = (yield pathExists(VERSION_PATH))
        ? fse.readFileSync(VERSION_PATH, 'utf8')
        : null;
    const shouldDownload = versionString !== TARGET_MINT_VERSION;
    if (shouldDownload) {
        const hasInternet = yield isOnline();
        if (!hasInternet) {
            logger.fail('Running mintlify dev afer updating requires an internet connection.');
            process.exit(1);
        }
        yield downloadTargetMint(logger);
    }
    // clear preexisting prebuild files
    fse.emptyDirSync(NEXT_PUBLIC_PATH);
    fse.emptyDirSync(NEXT_PROPS_PATH);
    process.chdir(CLIENT_PATH);
    try {
        yield prebuild(CMD_EXEC_PATH);
    }
    catch (err) {
        const errorText = err instanceof Error && err.message ? err.message : 'Prebuild step failed';
        logger.fail(errorText);
        process.exit(1);
    }
    logger.succeed('Local Mintlify instance is ready. Launching your site...');
    yield run(argv.port || '3000');
});
const run = (port) => __awaiter(void 0, void 0, void 0, function* () {
    const { default: Server } = yield import(pathToFileURL(NEXT_SERVER_PATH).href);
    const NextServer = Server.default;
    const { config } = yield JSON.parse(fse.readFileSync(NEXT_CONFIG_PATH, 'utf8'));
    process.chdir(CLIENT_PATH);
    let handler;
    const app = express();
    const server = createServer(app);
    const io = new SocketServer(server);
    const onChange = () => {
        io.emit('reload');
    };
    // static files don't get served in minimalMode
    app.use('/_next/static', express.static(NEXT_STATIC_PATH));
    // next-server is bugged, public files added after starting aren't served
    app.use('/', express.static(NEXT_PUBLIC_PATH));
    app.all('*', (req, res) => handler === null || handler === void 0 ? void 0 : handler(req, res));
    const currentPort = parseInt(port, 10) || 3000;
    const hostname = process.env.HOSTNAME || 'localhost';
    server.listen(currentPort, () => {
        const nextServer = new NextServer({
            hostname,
            port: currentPort,
            dir: CLIENT_PATH,
            dev: true,
            minimalMode: true,
            customServer: true,
            conf: config,
        });
        handler = nextServer.getRequestHandler();
        console.log(`🌿 ${Chalk.green(`Your local preview is available at http://localhost:${port}`)}`);
        console.log(`🌿 ${Chalk.green('Press Ctrl+C any time to stop the local preview.')}`);
        /**
         * We're running into a known bug with the `open` package, where Windows machines error out because process.env.SYSTEMROOT is not set:
         * https://github.com/sindresorhus/open/issues/292
         *
         * Let's use the same workaround that this project did:
         * https://github.com/sanity-io/sanity/pull/4221/files#diff-aeb574e1becf61f21fdf87fbea709669c93d604d660dad4b0f9e24527a2fb54bR256-R262
         */
        maybeFixMissingWindowsEnvVar();
        void open(`http://localhost:${port}`);
        // exit with successful status
        const onExit = () => {
            process.exit(0);
        };
        process.on('SIGINT', onExit);
        process.on('SIGTERM', onExit);
    });
    listener(onChange);
});
export default dev;
